package redis

import (
	"errors"
	"github.com/FZambia/sentinel"
	"github.com/gomodule/redigo/redis"
	"time"
)

func InitRedisSentinel(setting Setting) *Pool {
	checkSetting(&setting)

	sentinelConn := &sentinel.Sentinel{
		Addrs:      setting.Addr,
		MasterName: setting.Name,
		Dial: func(addr string) (redis.Conn, error) {
			c, err := redis.Dial("tcp", addr,
				redis.DialConnectTimeout(setting.ConnectTimeout),
				redis.DialWriteTimeout(setting.DoWithTimeout),
				redis.DialReadTimeout(setting.DoWithTimeout),
			)
			if err != nil {
				return nil, err
			}
			return c, nil
		},
	}

	pool := &redis.Pool{
		MaxIdle:     3,
		MaxActive:   64,
		Wait:        true,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			masterAddr, err := sentinelConn.MasterAddr()
			if err != nil {
				return nil, err
			}
			c, err := redis.Dial("tcp", masterAddr,
				redis.DialConnectTimeout(setting.ConnectTimeout),
				redis.DialWriteTimeout(setting.DoWithTimeout),
				redis.DialReadTimeout(setting.DoWithTimeout),
			)
			if err != nil {
				return nil, err
			}
			return c, nil
		},
		// 只读主节点
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if !sentinel.TestRole(c, "master") {
				return errors.New("sentinel role check failed")
			} else {
				return nil
			}
		},
	}

	return &Pool{
		pool:    pool,
		Name:    setting.Name,
		timeout: setting.DoWithTimeout,
		Type:    "sentinel",
	}
}
